Chapter 5: Exercises

選擇題


簡答題

  1. 請寫一段用戶端的 JavaScript 函數,其功能為使用非遞迴的方式來計算正整數 n 的階乘。
  2. 請寫一段用戶端的 JavaScript 函數,其功能為使用遞迴的方式來計算正整數 n 的階乘。
  3. 若有一個 JavaScript 函數,名稱是 abc,請問我們如何在此函數內取得輸入參數的個數?如何取得第一個參數?第二個參數?
  4. 請問 setTimeOut() 和 clearTimeOut() 的功能為何?請舉實例說明。
  5. 請問 setInterval() 和 clearInterval() 的功能為何?請舉實例說明。

程式題

請使用本章所學到 JavaScript 有關函數的程式技巧來完成下列作業:
  1. (*) 圓的周長和面積之一: 請寫一個網頁 circleArea.htm,包含一個連結「圓的周長和面積」,具有下列功能:
    • 當你按下此連結時,會跳出一個提示視窗,要求你輸入一個正數,做為一個圓的半徑。
    • 此程式會算出此圓的周長和面積,並將結果顯示在網頁上面。(請用兩個函數來完成這個作業。)
    (提示:你可以使用 Math.PI 來代表圓週率,會比 3.1415926 來的精準。)
  2. (*) 圓的周長和面積之二: 同前一小題,但請用一個函數來完成,此函數可以傳回一個陣列,包含兩個元素,分別是圓的周長和面積。(此網頁名稱是 circleArea2.htm。)
  3. (**) 計算Fibonacci數列的遞迴函數: 請寫一個網頁 FiboRecursive.htm,包含一個遞迴函數 fibo(n),可用來計算第 n 項的 Fibonacci 數列,此數列的定義如下: fibo(0)=0 fibo(1)=1 fibo(n)=fibo(n-1)+fibo(n-2),當 n 大於或等於 2 請呼叫此函數,並在網頁列出從 n = 0 到 n = 20 的 fibo(n) 值。
  4. (**) 計算Fibonacci數列的非遞迴函數: 請重複上題,寫一個網頁 FiboForLoop.htm,但改用迴圈方式(非遞迴)的函數來完成。
    (提示:有兩種方式來完成非遞迴的 Fibonacci 函數:
    • 你可以在函數內宣告一個陣列,以便儲存 fibo[0], fibo[1], fibo[2] 等等的值,以便直接取用而不必重新算起。
    • 你可以直接使用 Fibonacci 數列在第 n 項的數學式。(修過離散數學的同學都應該知道吧?)
    。)
  5. (***) 計算時間比較:以「遞迴方式」和「迴圈方式」來產生Fibonacci數列: 本題包含前面兩題。
    1. 請寫一個函數定義檔 fibonacci.js,裡面包含兩個函數,分別是遞迴函數 fiboRecursive() 和非遞迴函數(使用迴圈) fiboForloop()。
    2. 請寫一個網頁 fiboSpeedTest.htm,分別呼叫此函數,並進行計時,最後在網頁列出從 n = 20 到 n = 30 時,計算 fiboRecursive(n) 和 fiboForloop(n) 所花的時間,所列出的表格格式如下:
      n遞迴方式迴圈方式
      20[計算fiboRecursive(20)所花的時間][計算fiboForloop(20)所花的時間]
      21[計算fiboRecursive(21)所花的時間][計算fiboForloop(21)所花的時間]
      .
      .
      .
      .
      .
      .
      .
      .
      .
      30[計算fiboRecursive(30)所花的時間][計算fiboForloop(30)所花的時間]
    3. 你將會發現,電腦在計算fiboForloop(n)所花的計算時間會比fiboRecursive(n)少了很多,你能解釋原因嗎?
  6. (***) 計算時間比較:以「遞迴方式」和「迴圈方式」來產生組合個數: 一般組合個數是以 $C_n^m$ 來表示,代表「由 m 個物件中,任意取出 n 個物件的所有可能情況個數」,其數學解析式為: $$ C_n^m = \frac{m!}{(m-n)!n!} $$ 若不使用數學解析式,我們也可以使用下列遞迴式來表示: $$ C_n^m = C_{n-1}^{m-1} + C_{n}^{m-1} $$ (還記得此遞迴式所代表的意義吧?)請重複上題,但改成組合數的運算,而列表則改成由 m = 10~20,而對應的 n 則是 m 的一半(小數不計)。(提醒:請特別注意邊界條件的指定。)
  7. (*) 丟出去可回收的手榴彈之一: 請寫一個網頁 avoidableGrenade01.htm,包含一個按鈕,功能如下:
    1. 按鈕表面的文字是「丟手榴彈」。
    2. 按下按鈕後,文字變成「按下代表後悔,不然5秒內引爆...」
    3. 若使用者在5秒內按下按鈕,則沒事,按鈕文字恢復成「丟手榴彈」。
    4. 若使用者未在5秒內按下按鈕,則引爆手榴彈(跳出「轟!!!」的警告視窗),按鈕文字恢復成「丟手榴彈」。
    (提示:使用 setTimeout() 和 clearTimeout(),程式碼會比較簡潔。)
  8. (**) 丟出去可回收的手榴彈之二: 此題類似前一題,請寫一個網頁 avoidableGrenade02.htm,包含一個按鈕,功能如下:
    1. 按鈕表面的文字是「丟手榴彈」。
    2. 按下按鈕後,文字變成「按下代表後悔,不然5秒內引爆...」,但此文字會隨著時間而變化,秒數會變成「5秒」、「4秒」、「3秒」等等,直到引爆或取消。
    3. 若使用者在5秒內按下按鈕,則沒事,按鈕文字恢復成「丟手榴彈」。
    4. 若使用者未在5秒內按下按鈕,則引爆手榴彈(跳出「轟!!!」的警告視窗),按鈕文字恢復成「丟手榴彈」。
  9. (**) 左右跑馬燈: 請寫一個網頁 movingTextLeftRight.htm,包含類似下列的表單:

    功能如下:
    1. 按下「<===」按鈕,跑馬燈文字往左邊跑。
    2. 按下「===>」按鈕,跑馬燈文字往右邊跑。
    3. 按下「STOP」按鈕,跑馬燈文字靜止不動。
    (提示:使用 setInterval() 和 clearInterval(),程式碼會比較簡潔。)

JavaScript 程式設計與應用:用於網頁用戶端